home *** CD-ROM | disk | FTP | other *** search
- PAGE 60,132
- TITLE SPOOL - SPOOL PRINTER TO DISK
- COMMENT *
- SPOOL: THIS DOS COMMAND SPOOLS EVERYTHING WHICH GOES TO THE
- PARALLEL PRINTER TO A DISK FILE. DATA IS COLLECTED UNTIL
- A SECOND SPOOL COMMAND IS ISSUED.
-
- FORMAT:
- SPOOL <FILENAME>
-
- IF NO <FILENAME> IS GIVEN, THE PREVIOUS FILE IS
- CLOSED AND ALL FURTHER PRINTER DATA GOES TO THE
- PRINTER.
-
- PROGRAMMER: DON D WORTH - UCLA/OAC - 1/5/84
-
- ENTRY POINTS: +100 = STANDARD INITIAL COMMAND ENTRY
- +103 = PRINTER INTERRUPT ENTRY POINT
-
- TO LINK: LINK SPOOL,SPOOL,SPOOL;
- DEBUG SPOOL.EXE
- N SPOOL.COM
- W
- Q
-
- *
- BUFSIZ EQU 200H ;SIZE OF DMA BUFFER
- ;
- CONOUT EQU 02H ; CONSOLE OUTPUT
- PRINT EQU 09H ; PRINT STRING
- OPEN EQU 0FH ; OPEN FILE
- CLOSE EQU 10H ; CLOSE FILE
- DELETE EQU 13H ; DELETE FILE
- MAKE EQU 16H ; MAKE FILE
- SETDMA EQU 1AH ; SET DMA ADDRESS
- WRITER EQU 22H ; RANDOM WRITE
- GETDMA EQU 2FH ; GET DMA ADDRESS
- ;
- BELL EQU 07H ;BELL
- CR EQU 0DH ;CARRIAGE RETURN
- LF EQU 0AH ;LINE FEED
- SPACE EQU 20H ;SPACE
- ;
- PGM GROUP ASEG,CSEG,DSEG
- ASSUME CS:PGM,DS:PGM
- ;
- ; PREFIX SEGMENT
- ;
- ASEG SEGMENT PARA COMMON 'CODE'
- INT20 LABEL NEAR
- DW ?
- MEMSIZ DW ? ;TOTAL MEMORY SIZE
- DB ?
- BDOS LABEL NEAR
- DB 5 DUP(?) ;LONG CALL TO DOS
- TERMAD DW ?,? ;TERMINATE ADDRESS
- CTLBRK DW ?,? ;CONTROL-BREAK EXIT
- DW 37 DUP(?) ;RESERVED
- FCB1 DB 16 DUP(?) ;FIRST FCB
- FCB2 DB 16 DUP(?) ;SECOND FCB
- DW ?,? ;RESERVED
- DMA DB 128 DUP(?) ;DMA SECTOR BUFFER
- ;
- ASEG ENDS
- ;
- ; DATA SEGMENT
- ;
- DSEG SEGMENT PARA PUBLIC 'DATA'
- ;
- MSG DB CR,LF,'SPOOL INSTALLED',CR,LF,'$'
- MSGOPN DB CR,LF,'NO ROOM IN DIRECTORY FOR SPOOL FILE',BELL,CR,LF,'$'
- ;
- DSEG ENDS
- ;
- ; START OF CODE
- ;
- CSEG SEGMENT PARA PUBLIC 'CODE'
- ;
- ; NORMAL COMMAND ENTRY
- ;
- SPOOL: JMP INIT ;GO TO INIT CODE
- ;
- ; PARALLEL PRINTER INTERRUPT EXIT - INT 17H
- ;
- INTENT: STI ;INTERRUPTS BACK ON
- PUSH DS
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH AX
- MOV SI,CS
- MOV DS,SI ;SET UP DATA SEGMENT
- CMP BYTE PTR FLAG,0 ;IS FILE AVAILABLE?
- JNZ MYINT ;YES, GO ON
- POP AX
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP DS
- JMP DWORD PTR CS:VEC ;ELSE, GO TO REAL EXIT
- ;
- MYINT: OR AH,AH ;AH=0 : PRINT CHARACTER IN AL
- JNZ INTEXT
- MOV SI,SS
- MOV WORD PTR STKSAV+2,SI ;SAVE CALLER'S STACK
- MOV SI,SP
- MOV WORD PTR STKSAV,SI
- MOV SI,CS
- MOV SS,SI ;GIVE ME NEW BIGGER STACK
- MOV SI,OFFSET PGM:STK
- MOV SP,SI
- CALL PRNT ;PRINT THE CHARACTER
- MOV SI,WORD PTR STKSAV
- MOV SP,SI ;RESTORE CALLER'S STACK
- MOV SI,WORD PTR STKSAV+2
- MOV SS,SI
- ;
- INTEXT: POP AX ;ALL OTHERS PRODUCE ZERO RC
- MOV AH,90H ;SIMULATE BUSY/SELECTED
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP DS
- IRET
- ;
- ; ADD CHARACTER TO PRINT BUFFER
- ;
- PRNT: CMP BYTE PTR FLAG,0 ;MAKE SURE A FILE IS AVAIL.
- JZ INTEXT
- PUSH AX
- CMP WORD PTR LEFT,BUFSIZ ;BUFFER FULL?
- JNE INTADD ;NO
- CALL FLUSH ;YES, FLUSH BUFFER
- INTADD: POP AX
- MOV BX,WORD PTR LEFT
- ADD BX,OFFSET PGM:BUFFER
- MOV [BX],AL ;MOVE BYTE TO BUFFER
- INC WORD PTR LEFT
- RET: RET ;DONE FOR NOW
- ;
- ; FLUSH PRINT BUFFER TO DISK FILE
- ;
- FLUSH: XOR AX,AX
- CMP AX,WORD PTR DS:LEFT ;BUFFER NON-EMPTY?
- JE RET ;EMPTY, SKIP IT
- MOV WORD PTR DS:LEFT,AX ;ELSE, RESET IT
- ;
- PUSH ES
- PUSH DS
- ;
- ; EL KLUDGEO: PRESERVE A CHUNK OF DOS 2.0 ACROSS INT 21H
- ;
- MOV AX,DS ;COPY TO MY SEGMENT
- MOV ES,AX
- MOV AX,DS:STKSAV+2 ;COPYING FROM CALLER'S STACK
- MOV DS,AX
- MOV SI,0 ;MAGIC OFFSET TO DOS'S STACK
- MOV DI,(OFFSET PGM:DOSSTK)
- MOV CX,0C80H ;LENGTH TO SAVE
- CLD
- REP MOVSB ;COPY DOS'S STACK
- POP DS
- PUSH DS
- ;
- MOV AH,GETDMA
- INT 21H
- PUSH ES ;SAVE OLD DMA ADDR
- PUSH BX
- MOV DX,OFFSET PGM:BUFFER
- MOV AH,SETDMA
- INT 21H ;SET UP MY DMA
- MOV DX,OFFSET PGM:FCB
- MOV AH,OPEN
- INT 21H ;REOPEN FILE
- ;
- MOV AX,WORD PTR DS:CURREC
- MOV WORD PTR DS:FCB+33,AX ;SET NEW RECORD TO WRITE
- MOV WORD PTR DS:FCB+14,BUFSIZ ;AND RECORD SIZE
- MOV DX,OFFSET PGM:FCB
- MOV AH,WRITER
- INT 21H ;WRITE BUFFER TO DISK
- OR AL,BYTE PTR DS:SAVE ;SAVE RC
- MOV BYTE PTR DS:SAVE,AL
- INC WORD PTR DS:CURREC ;NEXT RECORD NEXT TIME
- ;
- MOV DX,OFFSET PGM:FCB
- MOV AH,CLOSE
- INT 21H ;CLOSE THE FILE TO FLUSH BUFFS
- POP DX
- POP DS
- MOV AH,SETDMA ;RESTORE OLD DMA
- INT 21H
- ;
- POP DS
- POP ES
- ;
- CMP BYTE PTR DS:SAVE,'0' ;DID IT WORK?
- JNE IOERR
- ;
- FLHOUT: MOV AX,DS:STKSAV+2 ;COPYING TO DOS'S WORKAREA
- CMP AX,100H
- JA FRET ;MUST BE DOS'S SEGMENT
- PUSH ES
- MOV ES,AX
- MOV DI,0 ;RESTORE DATA AREAS
- MOV SI,(OFFSET PGM:DOSSTK)
- MOV CX,0C80H ;LENGTH TO RESTORE
- CLD
- REP MOVSB ;COPY DOS'S STACK
- POP ES ;RESTORE ES
- FRET: RET
- ;
- IOERR: XOR AX,AX
- INT 10H ;CLEAR SCREEN
- MOV SI,(OFFSET PGM:MSGERR)
- MSGLP: MOV AL,[SI] ;GET NEXT CHARACTER
- CMP AL,'$' ;END OF MESSAGE?
- JE IOEOUT
- XOR BX,BX ;NO...
- MOV AH,14
- INT 10H ;WRITE CHARACTER
- INC SI
- JMP MSGLP
- IOEOUT: MOV BYTE PTR DS:FLAG,0 ;MARK FILE CLOSED
- JMP FLHOUT
- ;
- ; PERMANENT DATA AREA (ALWAYS USE DS: FROM CODE BELOW)
- ;
- FLAG DB 0 ;FILE OPEN FLAG
- FCB DB 37 DUP(0) ;FILE CONTROL BLOCK
- MSGERR DB BELL,BELL,BELL,'SPOOL WRITE ERROR - '
- SAVE DB '0$'
- VEC DD 0 ;OLD PRINT INT HANDLER
- LEFT DW 0 ;BYTES LEFT IN DMA BUFFER
- CURREC DW 0 ;CURRENT RECORD TO WRITE
- BUFFER DB BUFSIZ DUP(?) ;WRITE BUFFER
- DOSSTK DB 0C80H DUP(?) ;PLACE TO SAVE INT 21H'S STACK
- STKSAV DD 0 ;CALLER'S STACK EA
- DB 64 DUP('STACK ')
- STK EQU THIS BYTE
- ;
- ; SEE IF A FILE IS ALREADY OPEN
- ;
- INIT: CALL CHKVEC ;FIND PREVIOUS WORKAREA
- CMP BYTE PTR DS:FLAG,0 ;FILE OPEN OR CLOSED?
- JE NOCLS ;CLOSED, NO CLOSE NEEDED
- MOV AL,1AH
- MOV WORD PTR DS:STKSAV+2,AX ;MAKE SURE WE DON'T RESTORE STUFF
- CALL PRNT ;PRINT END OF FILE MARK
- CALL FLUSH ;FLUSH OUT WRITE BUFFER
- MOV BYTE PTR DS:FLAG,0 ;NO LONGER OPEN
- ;
- ; COPY NEW FCB1 TO PERMANENT FCB
- ;
- NOCLS: CMP BYTE PTR ES:FCB1+1,20H ;BLANK FILENAME?
- JE INSTAL ;THEN DON'T OPEN IT
- MOV SI,(OFFSET PGM:FCB1)
- MOV DI,(OFFSET PGM:FCB)
- MOV CX,35 ;LENGTH OF AN FCB
- PUSH ES
- PUSH DS
- POP ES ;SWAP SEGMENTS
- POP DS
- CLD
- REP MOVSB ;MOVE IT
- PUSH ES
- PUSH DS
- POP ES
- POP DS ;SWAP SEGMENTS BACK
- ;
- ; OPEN NEW FCB
- ;
- MOV DX,(OFFSET PGM:FCB)
- MOV AH,DELETE
- INT 21H ;DELETE OLD FILE
- MOV DX,(OFFSET PGM:FCB)
- MOV AH,MAKE
- INT 21H ;CREATE IT
- CMP AL,0FFH
- JNE ITSOPN ;ALL WENT WELL?
- MOV DX,(OFFSET PGM:MSGOPN)
- MOV AH,PRINT
- INT 21H ;'OPEN FAILED'
- XOR AX,AX
- INT 21H ;TERMINATE
- ;
- ; SET UP OPEN FILE, CLEAR BUFFER
- ;
- ITSOPN: MOV BYTE PTR DS:FLAG,0FFH ;MARK FILE AS OPEN
- MOV WORD PTR DS:CURREC,0 ;RESET CURRENT RECORD
- MOV WORD PTR DS:LEFT,0 ;NOTHING IN WRITE BUFFER NOW
- ;
- MOV AH,CLOSE
- MOV DX,(OFFSET PGM:FCB)
- INT 21H ;CLOSE FILE UNTIL WE NEED IT
- ;
- ; INSTALL PRINT INTERCEPT IF NECESSARY
- ;
- INSTAL: CALL CHKVEC ;IS ONE ALREADY INSTALLED?
- JE EXIT ;YES, NOTHING ELSE TO DO
- PUSH DS
- XOR AX,AX
- MOV DS,AX
- MOV AX,WORD PTR DS:005CH ;SAVE OLD VECTOR
- MOV WORD PTR CS:VEC,AX
- MOV AX,WORD PTR DS:005EH
- MOV WORD PTR CS:VEC+2,AX
- MOV AX,(OFFSET PGM:INTENT)
- MOV WORD PTR DS:005CH,AX ;INSTALL PARALLEL INT
- MOV AX,CS
- MOV WORD PTR DS:005EH,AX
- POP DS
- ;
- MOV DX,OFFSET PGM:MSG
- MOV AH,PRINT
- INT 21H ;'SPOOL INSTALLED'
- ;
- ; EXIT LEAVING ME IN MEMORY
- ;
- MOV DX,OFFSET PGM:INIT
- INT 27H ;EXIT BUT STAY RESIDENT
- ;
- ; EXIT NORMALLY
- ;
- EXIT: MOV AX,CS ;PUT BACK SEGMENT
- MOV DS,AX
- XOR AX,AX
- INT 21H ;EXIT COMPLETELY
- ;
- ; CHECK PARALLEL PRINTER VECTOR FOR INTERCEPT
- ;
- CHKVEC: XOR AX,AX ;CHECK INT VECTORS
- MOV DS,AX ;FOR PARALLEL PRINTER
- MOV AX,WORD PTR DS:005CH ;GET OFFSET PART
- CMP AX,(OFFSET PGM:INTENT) ;SAME AS MY INTERCEPT'S
- JE SETES ;IF SO, USE OLD COPY
- MOV AX,CS ;RESTORE DS REG
- MOV DS,AX
- RET
- SETES: MOV AX,WORD PTR DS:005EH ;GET SEGMENT OF OTHER ME
- MOV DS,AX ;AND USE IT INSTEAD
- RET ; CS: AND ES: REMAIN THE SAME
- ;
- CSEG ENDS
- END